package gr.aueb.mscis.chord;

import gr.aueb.mscis.protocol.NodeIdentifier;
import gr.aueb.mscis.protocol.ProtocolType;
import gr.aueb.mscis.protocol.RemoteMessage;
import gr.aueb.mscis.utils.Details;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.net.Socket;

import android.util.Log;

public class RemoteMessageDaemonThread extends Thread {

	private ObjectInputStream ois;
	private ObjectOutputStream oos;

	private Socket socket = null;

	private Node node;

	public RemoteMessageDaemonThread(Socket socket, Node node) {
		super("RemoteMessageDaemonThread");
		this.socket = socket;
		this.node = node;
	}

	public void run() {
		listen();
	}

	public void listen() {
		
		try {
			ois = new ObjectInputStream(socket.getInputStream());
		} catch (StreamCorruptedException e1) {
		} catch (IOException e1) {
		}
		try {
			RemoteMessage message = (RemoteMessage) ois.readObject();

			// respond to synchronous calls
			if (message.getProtocolType().equals(ProtocolType.FIND_SUCCESSOR)) {
				
				// elegxei gia to an zitaei finger i successor. H klasi details
				// 8a periexei true/false sto findFinger
				if (message.getPayload() != null) {
					if (((Details) message.getPayload()).isFindFinger()) {/*
																		 * xeirismos
																		 * gia
																		 * to
																		 * find
																		 * hash
																		 */
						node.find_successor(message.getNodeId().getHash(),
								message.getNodeId(),
								((Details) message.getPayload()).getPosition());
					}

				} else {
					// Otan eiserxetai enas komvos sto daktylio anazhteitai to
					// hashId tou komvou pou einai o telikos proorismos
					node.find_successor(message.getNodeId().getHash(),
							message.getNodeId(), -1);
				}

				

			} else if (message.getProtocolType().equals(ProtocolType.FIND_SUCCESSOR_REPLY)) {
				if (message.getPayload() == null) {
					node.setSuccessor(message.getNodeId());
				}
				else
					Node.fingerTable[((Details) message.getPayload()).getPosition()] = message.getNodeId();
			}
			else if (message.getProtocolType().equals(ProtocolType.GET_SUCCESSOR_LIST)){
				oos = new ObjectOutputStream(socket.getOutputStream());
				oos.writeObject(new RemoteMessage(null, new NodeIdentifier[] {Node.successorList[0], Node.successorList[1]}, node.getNodeId()));
				oos.close();
			}
			
			else if (message.getProtocolType().equals(ProtocolType.GET_PREDECESSOR)){
				Log.v("stabilize", "elave GET_PREDECESSOR");
				if(node.getPredecessor() == null)
				{
					Log.v("stabilize", "allaxe ton predecessor mou");
					node.setPredecessor(message.getNodeId());
				}
				
				oos = new ObjectOutputStream(socket.getOutputStream());
				oos.writeObject(new RemoteMessage(null, null, node.getPredecessor()));
				
				/*PROSOXH - ayth ekteleitai mono otan to getPredecessor kaleitai apo to stabilize. An klhthei apo allou prepei na ftiaxoume neo protocol type*/
				node.notify(message.getNodeId());
				
				oos.close();
			}
			
			if (socket != null) {
				socket.close();
			}

		} catch (IOException e) {
		} catch (ClassNotFoundException e) {
		}
		
		
	}

}
